﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Runtime.Serialization;
using System.IO.IsolatedStorage;
using System.Collections.ObjectModel;
using System.Runtime.Serialization.Json;
using Kindohm.KSynth.Library;

namespace Kindohm.KSynth.UI
{
    public class PresetRepository
    {
        static PresetRepository instance;
        ObservableCollection<Preset> presets;

        PresetRepository()
        {
            this.PresetErrors = new List<string>();
        }

        public static PresetRepository Instance
        {
            get
            {
                if (PresetRepository.instance == null)
                    PresetRepository.instance = new PresetRepository();
                return PresetRepository.instance;
            }
        }

        public List<string> PresetErrors { get; set; }

        public ObservableCollection<Preset> Presets
        {
            get
            {
                if (this.presets == null)
                    this.LoadPresets();
                return this.presets;
            }
        }

        void LoadPresets()
        {
            List<string> badPresets = new List<string>();
            ObservableCollection<Preset> items = new ObservableCollection<Preset>();
            using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                string[] fileNames = storage.GetFileNames("*.pre");

                for (int i = 0; i < fileNames.Length; i++)
                {
                    using (IsolatedStorageFileStream stream = storage.OpenFile(fileNames[i], FileMode.Open))
                    {
                        using (StreamReader reader = new StreamReader(stream))
                        {
                            string json = reader.ReadToEnd();

                            using (MemoryStream ms = new MemoryStream(
                                Encoding.Unicode.GetBytes(json)))
                            {
                                DataContractJsonSerializer serializer =
                                        new DataContractJsonSerializer(typeof(Preset));
                                try
                                {
                                    Preset preset = (Preset)serializer.ReadObject(ms);
                                    items.Add(preset);
                                }
                                catch (SerializationException ex)
                                {
                                    badPresets.Add(fileNames[i]);
                                    this.PresetErrors.Add(
                                        string.Format("Error loading preset {0}.  There was a problem with " +
                                        "the JSON data.  The preset will be deleted.  Sorry.", fileNames[i]));
                                }
                            }
                        }
                    }

                    foreach (string file in badPresets)
                    {
                        try
                        {
                            storage.DeleteFile(file);
                        }
                        catch (Exception ex)
                        {
                            //do nothing.  sorry.
                        }
                    }
                }
            }
            this.presets = items;
        }

        public Preset FindByNumber(int number)
        {
            var items = from item in this.Presets
                        where item.Number == number
                        select item;
            if (items.Count() > 0)
                return items.First();
            else
                return null;
        }

        public void SavePreset(Preset preset)
        {
            using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (IsolatedStorageFileStream stream =
                    storage.OpenFile("preset" + preset.Number + ".pre", FileMode.OpenOrCreate))
                {

                    string jsonString;

                    using (MemoryStream ms = new MemoryStream())
                    {
                        DataContractJsonSerializer serializer =
                               new DataContractJsonSerializer(preset.GetType());
                        serializer.WriteObject(ms, preset);
                        ms.Position = 0;
                        using (StreamReader reader = new StreamReader(ms))
                        {
                            jsonString = reader.ReadToEnd();
                        }
                    }

                    using (StreamWriter writer = new StreamWriter(stream))
                    {
                        writer.Write(jsonString);
                    }
                }
            }
        }

    }
}
